package com.cmc.cloud.cmclink.doc.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.lock.annotation.Lock4j;
import com.cmc.cloud.cmclink.doc.constants.errorconstant.VoyageBsaHgErrorCodeConstants;
import com.cmc.cloud.cmclink.doc.vo.voyagebsahgvo.VoyageBsaHgBaseVO;
import com.cmc.cloud.cmclink.doc.vo.voyagebsahgvo.VoyageBsaHgCreateReqVO;
import com.cmc.cloud.cmclink.doc.vo.voyagebsahgvo.VoyageBsaHgPageReqVO;
import com.cmc.cloud.cmclink.doc.vo.voyagebsahgvo.VoyageBsaHgUpdateReqVO;
import com.cmes.framework.mybatis.core.query.LambdaQueryWrapperX;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;


import com.cmes.framework.common.pojo.PageResult;
import com.cmes.framework.common.exception.util.ServiceExceptionUtil;

import java.util.*;

import com.cmc.cloud.cmclink.doc.service.VoyageBsaHgService;
import com.cmc.cloud.cmclink.doc.entity.VoyageBsaHgDO;
import com.cmc.cloud.cmclink.doc.mapper.VoyageBsaHgMapper;


/**
 * 高箱计算标准 Service 实现类
 *
 * @author 招商轮船-管理员
 */
@Service
@Validated
public class VoyageBsaHgServiceImpl implements VoyageBsaHgService {

    @Resource
    private VoyageBsaHgMapper voyageBsaHgMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    @Lock4j(name = "voyageBsaHgUnique", keys = {"#createReqVO.getCntrType", "#createReqVO.getCntrSize", "#createReqVO.getVoyageBsaId"})
    public void createVoyageBsaHg(VoyageBsaHgCreateReqVO createReqVO) {
        // 插入
        validateUniqueExists(createReqVO, null);
        VoyageBsaHgDO voyageBsaHg = BeanUtil.copyProperties(createReqVO, VoyageBsaHgDO.class);
        voyageBsaHgMapper.insert(voyageBsaHg);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @Lock4j(name = "voyageBsaHgUnique", keys = {"#updateReqVO.getCntrType", "#updateReqVO.getCntrSize", "#updateReqVO.getVoyageBsaId"})
    public void updateVoyageBsaHg(VoyageBsaHgUpdateReqVO updateReqVO) {
        // 校验存在
        validateVoyageBsaHgExists(updateReqVO.getId());
        validateUniqueExists(updateReqVO, updateReqVO.getId());
        // 更新
        VoyageBsaHgDO updateObj = BeanUtil.copyProperties(updateReqVO, VoyageBsaHgDO.class);
        voyageBsaHgMapper.updateById(updateObj);
    }

    @Override
    public void deleteVoyageBsaHg(Long id) {
        // 校验存在
        validateVoyageBsaHgExists(id);
        // 删除
        voyageBsaHgMapper.deleteById(id);
    }

    private void validateVoyageBsaHgExists(Long id) {
        if (voyageBsaHgMapper.selectById(id) == null) {
            throw ServiceExceptionUtil.exception(VoyageBsaHgErrorCodeConstants.VOYAGE_BSA_HG_NOT_EXISTS);
        }
    }

    private void validateUniqueExists(VoyageBsaHgBaseVO vo, Long id) {
        LambdaQueryWrapperX<VoyageBsaHgDO> queryWrapperX = new LambdaQueryWrapperX<VoyageBsaHgDO>()
                .eqIfPresent(VoyageBsaHgDO::getVoyageBsaId, vo.getVoyageBsaId())
                .eqIfPresent(VoyageBsaHgDO::getCntrSize, vo.getCntrSize())
                .eqIfPresent(VoyageBsaHgDO::getCntrType, vo.getCntrType());
        if (id != null) {
            queryWrapperX.ne(VoyageBsaHgDO::getId, id);
        }
        if (voyageBsaHgMapper.selectCount(queryWrapperX) != 0L) {
            throw ServiceExceptionUtil.exception(VoyageBsaHgErrorCodeConstants.VOYAGE_BSA_HG_EXISTED);
        }
    }

    @Override
    public VoyageBsaHgDO getVoyageBsaHg(Long id) {
        return voyageBsaHgMapper.selectById(id);
    }

    @Override
    public List<VoyageBsaHgDO> getVoyageBsaHgByMainId(Long id) {
        return voyageBsaHgMapper.selectList(new LambdaQueryWrapperX<VoyageBsaHgDO>().eq(VoyageBsaHgDO::getVoyageBsaId, id));
    }

    @Override
    public List<VoyageBsaHgDO> getVoyageBsaHgList(Collection<Long> ids) {
        return voyageBsaHgMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<VoyageBsaHgDO> getVoyageBsaHgPage(VoyageBsaHgPageReqVO reqVO) {
        LambdaQueryWrapperX<VoyageBsaHgDO> queryWrapperX = new LambdaQueryWrapperX<>();
        return voyageBsaHgMapper.selectPage(reqVO, queryWrapperX);
    }
}
